package org.xxpay.pay.channel.vip;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.xxpay.common.http.HttpConfigStorage;
import org.xxpay.common.http.HttpRequestTemplate;
import org.xxpay.common.util.sign.SignUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.AmountUtil;
import org.xxpay.core.entity.TransOrder;
import org.xxpay.pay.channel.BaseTrans;
import org.xxpay.pay.channel.shengfutong.SftpayConfig;

import java.util.HashMap;
import java.util.Map;

@Component
public class VippayTransService extends BaseTrans {

    private final static String logPrefix = "【VIP】";

    private final static String AGENT_PAY_REQUEST_STR = "/api/pay";
    private final static String AGENT_PAY_QUERY_REQUEST_STR = "/api/payquery";
    private final static String AGENT_PAY_BALANCE_STR = "/api/balance";

    @Override
    public String getChannelName() {
        return VippayConfig.CHANNEL_NAME;
    }

    /**
     * 代付订单
     *
     * @param transOrder
     * @return
     */
    @Override
    public JSONObject trans(TransOrder transOrder) {
        JSONObject retObj = buildRetObj();
        VippayConfig vippayConfig = new VippayConfig(getTransParam(transOrder));
        Map<String, Object> parameters = buildRequstParam(vippayConfig, transOrder);
        _log.info("{}申请代付请求参数：{}", logPrefix, parameters.toString());
        HttpConfigStorage httpConfigStorage = new HttpConfigStorage();
        httpConfigStorage.setMaxTotal(5);
        httpConfigStorage.setDefaultMaxPerRoute(3);
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(httpConfigStorage);
        JSONObject origin = requestTemplate.postForObject(getReqUrl(vippayConfig.getRequestUrl(), AGENT_PAY_REQUEST_STR), parameters, JSONObject.class);
        _log.info("{}申请代付响应参数：{}", logPrefix, origin.toJSONString());

        retObj.put("isSuccess", false);
        retObj.put("transOrderId", transOrder.getTransOrderId());
        if (StringUtils.equals(SftpayConfig.RESPONSE_RESULT_SUCCESS, origin.getString("err"))) {
            JSONObject msg = origin.getJSONObject("msg");
            retObj.put("channelOrderNo", msg.getString("yfb_order_sn"));
            retObj.put("isSuccess", true);
            // 1. 处理中 2. 成功 3. 失败
            retObj.put("status", 1);
            return retObj;
        }
        // 1. 处理中 2. 成功 3. 失败
        retObj.put("status", 3);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, "下单失败[" + origin.getString("msg") + "]");
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        return retObj;
    }

    /**
     * 构建实时代付请求参数
     *
     * @return
     */
    private Map<String, Object> buildRequstParam(VippayConfig vippayConfig, TransOrder transOrder) {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("app_id", vippayConfig.getMchId());
        parameters.put("order_sn", transOrder.getTransOrderId());
        parameters.put("amount", AmountUtil.convertCent2DollarShort(String.valueOf(transOrder.getAmount())));
        parameters.put("bank_name", transOrder.getBankName());
        parameters.put("branchbank", transOrder.getBankName());
        parameters.put("wallet_id", vippayConfig.getPayMode());
        parameters.put("user_name", transOrder.getAccountName());
        parameters.put("user_account", transOrder.getAccountNo());
        parameters.put("province", transOrder.getProvince());
        parameters.put("city", transOrder.getCity());
        parameters.put("signature", getSign(vippayConfig,parameters));
        return parameters;
    }

    /**
     * 订单查询接口
     *
     * @param transOrder
     * @return
     */
    @Override
    public JSONObject query(TransOrder transOrder) {
        VippayConfig vippayConfig = new VippayConfig(getTransParam(transOrder));

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("order_sn", transOrder.getTransOrderId());
        parameters.put("app_id", vippayConfig.getAppId());
        parameters.put("signature", getSign(vippayConfig,parameters));

        _log.info("{}代付查询请求参数：{}", logPrefix, parameters.toString());

        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        JSONObject origin = requestTemplate.postForObject(getReqUrl(vippayConfig.getRequestUrl(), AGENT_PAY_QUERY_REQUEST_STR), parameters, JSONObject.class);

        _log.info("{}代付查询响应参数：{}", logPrefix, origin.toJSONString());
        JSONObject retObj = buildRetObj();
        if (StringUtils.equals(VippayConfig.RETURN_VALUE_SUCCESS, origin.getString("err"))) {
            retObj.put("isSuccess", true);
            retObj.put("transOrderId", transOrder.getTransOrderId());
            retObj.putAll(origin);
            /**
             *  status状态说明 1 => 成功 2 => 失败 3 => 取消 4 => 未支付
             */
            JSONObject msg =  origin.getJSONObject("msg");
            Integer status = msg.getInteger("pay_status");
            if (status == 1) {
                retObj.put("status", 2); // 2表示成功
            } else if (status == 2 || status == 3 || status == 4) {
                retObj.put("status", 3); // 3表示失败
            } else {
                retObj.put("status", 1); // 1处理中
            }
            retObj.put("channelOrderNo", origin.getString("transaction_id"));
            retObj.put("channelObj", origin);
            return retObj;
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.getString("msg"));
        retObj.put("channelErrCode", origin.getString("err"));
        retObj.put("isSuccess", false);
        return retObj;
    }

    /**
     * 余额查询接口
     *
     * @param payParam
     * @return
     */
    @Override
    public JSONObject balance(String payParam) {
        VippayConfig vippayConfig = new VippayConfig(payParam);
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("app_id", vippayConfig.getAppId());
        parameters.put("signature", getSign(vippayConfig,parameters));
        _log.info("{}代付余额查询请求参数：{}", logPrefix, parameters.toString());
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        JSONObject origin = requestTemplate.postForObject(getReqUrl(vippayConfig.getRequestUrl(), AGENT_PAY_BALANCE_STR), parameters, JSONObject.class);
        _log.info("{}代付余额查询响应参数：{}", logPrefix, origin.toJSONString());
        JSONObject retObj = buildRetObj();
        if (StringUtils.equals(VippayConfig.RETURN_VALUE_SUCCESS, origin.getString("err"))) {
            JSONObject bizContext = origin.getJSONObject("msg");
            JSONArray walletList = bizContext.getJSONArray("wallet");
            for (int i = 0; i <walletList.size() ; i++) {
                JSONObject wallet = walletList.getJSONObject(i);
                if (wallet.getString("wallet_id").equals(vippayConfig.getPayMode())){
                    String balance = wallet.getString("balance");
                    retObj.put("cashBalance", balance);
                    retObj.put("payBalance", balance);
                }
            }
            return retObj;
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.getString("msg"));
        return retObj;
    }

    private String getSign(VippayConfig vippayConfig, Map<String, Object> parameters) {
        String signTxt = SignUtils.parameterText(parameters);
        String sign = SignUtils.MD5.createSign(signTxt, "&"+vippayConfig.getPrivateKey(), SignUtils.CHARSET_UTF8);
        return sign.toUpperCase();
    }

}
